/*
 * Copyright (C) 2025 Tsingteng MicroSystem
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * @file discover_manager.c
 * @brief Discover Manager实现
 */
#include "nci_rf.h"
#include "nci_core.h"
#include "nfc_log_api.h"
#include "nfa_discover.h"
#include "nfa_ce.h"
#include "nci_module.h"
#include "nci_task.h"
#include "discover_int.h"
#include "nci_data.h"
#include "nfc_config_api.h"

#define NCI_REG_LA_BIT_FRAME_SDD 0x30
#define NCI_REG_LA_PLATFORM_CONFIG 0x31
#define NCI_REG_LB_SENSB_INFO 0x38
#define NCI_REG_LF_PROTOCOL_TYPE 0x50

#define RF_DISCOVER_ENTRY_MAX_SIZE 10
#define RF_DISCOVER_PARAM_MAX_SIZE 3

#define DISCOVERY_DURATION_DEFAULT 500
#define DISCOVERY_DURATION_READER_MODE 200

typedef struct {
    bool is_init;
    uint8_t la_bit_frame_sdd;
    uint8_t la_platform_config;
    uint8_t lb_sensb_info;
    uint8_t lf_protocol_type;
} tLISTEN_MODE_CONFIG;

extern bool g_dta_mode_enabled;

static tLISTEN_MODE_CONFIG s_listen_mode_config;
static uint16_t s_disc_duration;;

const static char *s_rfst_name[] = {
    "IDLE", "DISCOVERY", "W4_ALL_DISCOVERIES", "W4_HOST_SELECT", "POLL_ACTIVE", "LISTEN_ACTIVE", "LISTEN_SLEEP"
};

static tNCI_RF_DISCOVER_MAP_ENTRY s_rf_discover_map[] = {
    {NCI_RF_PROTOCOL_ISO_DEP, NCI_RF_DISCOVER_MODE_POLL_AND_LISTEN, NCI_RF_INTERFACE_ISO_DEP},
    {NCI_RF_PROTOCOL_M1, NCI_RF_DISCOVER_MODE_POLL, NCI_RF_INTERFACE_TAG_CMD},
};
static uint8_t s_rf_discover_map_size = sizeof(s_rf_discover_map) / sizeof(tNCI_RF_DISCOVER_MAP_ENTRY);

static uint8_t s_poll_tech_mask;        // 从config中读取的poll技术掩码
static uint8_t s_listen_tech_mask;      // 从config中读取的listen技术掩码
static uint8_t s_poll_tech;             // 当前使用的poll技术参数
static uint8_t s_listen_tech;           // 当前使用的listen技术参数
static bool s_curr_reader_mode = false; // 当前是否处于reader mode
static int s_user_listen_tech;          // 用户配置的listen技术
static int s_user_poll_tech;            // 用户配置的poll技术

static volatile tNCI_RFST s_rfst;
static tMUTEX s_discover_lock = MUTEX_INIT_VAL("discover");
static tATOMIC s_deactivate_flag = 0;

static tNCI_RF_DISCOVER_PARAMS *s_p_discover_params = NULL; // 缓存卡片发现参数的列表指针
static uint8_t s_discover_params_size = 0; // 当前已经接收到的卡片发现参数个数

/* @brief 等待激活事件的指针，当接收到6105时，如果此指针非空，则会将激活参数copy到此指针地址并且不通知RW/CE激活事件 */
static tNCI_RF_INTF_ACTIVATED_PARAMS *s_p_wait_activated_params = NULL;
/* @brief 是否阻止发送TAG_LOSTED事件，为true时当RF状态从POLL_ACTIVE或W4_HOST_SELECT变为IDLE或DISCOVERY时不发送TAG_LOSTED事件*/
static bool s_block_send_tag_lost_evt = false;

#define GET_DISCOVER_LOCK() \
    if (osi_mutex_lock(&s_discover_lock) != NFC_STATUS_OK) { \
        NFCLOG_E("GET_DISCOVER_LOCK failed"); \
        return NCI_STATUS_EXT_GET_LOCK_FAILED; \
    }
#define RELEASE_DISCOVER_LOCK() \
    if (osi_mutex_unlock(&s_discover_lock) != NFC_STATUS_OK) { \
        NFCLOG_E("RELEASE_DISCOVER_LOCK failed"); \
    }

static void update_rfst(tNCI_RFST new_rfst) {
    if (new_rfst >= NCI_RFST_MAX) {
        NFCLOG_E("new rfst is invalid: %d", new_rfst);
        return;
    }
    NFCLOG_I("update rf_state: %s(%d) -> %s(%d)", s_rfst_name[s_rfst], s_rfst, s_rfst_name[new_rfst], new_rfst);
    if (new_rfst == NCI_RFST_IDLE || new_rfst == NCI_RFST_DISCOVERY) {
        if (s_p_discover_params) {
            // 回到IDLE和DISCOVERY状态时，清空发现的参数列表
            osi_free(s_p_discover_params);
            s_discover_params_size = 0;
        }
        if (s_rfst == NCI_RFST_POLL_ACTIVE || s_rfst == NCI_RFST_W4_HOST_SELECT) {
            // 通知卡片丢失
            if (!s_block_send_tag_lost_evt) {
                nci_task_post(NCI_TASK_EVT_RW_TAG_LOSTED, 0, 0, NULL);
            }
        }
    }
    s_rfst = new_rfst;
}

/**
 * @brief 获取当前的RF状态
 *
 * @return 当前RF状态
 */
tNCI_RFST nfa_rf_get_state() {
    if (osi_mutex_lock(&s_discover_lock) != NFC_STATUS_OK) { \
        NFCLOG_E("get discover lock failed"); \
        return NCI_RFST_MAX; \
    }
    tNCI_RFST curr_state = s_rfst;
    if (osi_mutex_unlock(&s_discover_lock) != NFC_STATUS_OK) { \
        NFCLOG_E("release discover lock failed"); \
    }
    return curr_state;
}

/**
 * @brief 设置RF Discover参数
 *
 * @param poll_param POLLING参数
 * @param listen_param LISTENING参数
 *
 * @note poll_param和listen_param为负数的情况表示此项参数保持原样，不修改
 * @note 此函数只是设置poll和listen参数，RF状态不会改变
 *
 * @return 成功返回NCI_STATUS_OK，失败返回其他错误码
 */
tNCI_STATUS rf_set_discover_param(int poll_param, int listen_param) {
    NFCLOG_I("set param: poll_param = %d, listen_param = %d", poll_param, listen_param);
    GET_DISCOVER_LOCK();
    if (poll_param >= 0) {
        s_poll_tech = (uint8_t) poll_param;
    }
    if (listen_param >= 0) {
        s_listen_tech = (uint8_t) listen_param;
    }
    RELEASE_DISCOVER_LOCK();
    return NCI_STATUS_OK;
}
/**
 * @brief 设置用户自定义的Discovery参数，此项目设置后，Discovery参数将完全以此值为准
 *
 * @note 此函数只能在IDLE和DISCOVERY状态下调用，其他状态调用会返回错误码
 *
 * @param poll_tech 用户自定义的POLLING技术, 不想设置时传NCI_RF_USER_DISCOVER_NOT_SET，取消设置时传NCI_RF_USER_DISCOVER_REVERT
 * @param listen_tech 用户自定义的LISTENING技术，不想设置时传NCI_RF_USER_DISCOVER_NOT_SET，取消设置时传NCI_RF_USER_DISCOVER_REVERT
 * @param restart_rf_discovery 是否重启RF Discovery
 *
 * @return 成功返回NCI_STATUS_OK，失败返回其他错误码
 */
tNCI_STATUS nfa_rf_set_user_discovery_tech(int poll_tech, int listen_tech, bool restart_rf_discovery) {
    NFCLOG_I("set user poll tech: %d, listen tech: %d, restart_rf_discovery=%d", poll_tech, listen_tech, restart_rf_discovery);
    GET_DISCOVER_LOCK();
    tNCI_STATUS ret = NCI_STATUS_EXT_FAILED;
    bool need_restart = false;
    switch (s_rfst) {
        case NCI_RFST_IDLE:
            // IDLE状态直接设置listen tech
            break;
        case NCI_RFST_DISCOVERY:
            if (restart_rf_discovery) {
                ret = nfa_rf_stop_discovery();
                if (ret != NCI_STATUS_OK) {
                    NFCLOG_E("stop discovery failed");
                    goto unlock;
                }
                need_restart = true;
            }
            break;
        default:
            // 其他状态不允许设置listen tech
            NFCLOG_E("current rf state:%s(%d) is not allow to set user listen tech", s_rfst_name[s_rfst], s_rfst);
            ret = NCI_STATUS_EXT_STATE_INCORRECT;
            goto unlock;
    }
    if (poll_tech == NCI_RF_USER_DISCOVER_REVERT) {
        s_user_poll_tech = -1;
    } else if (poll_tech >= 0) {
        s_user_poll_tech = poll_tech;
    }
    if (listen_tech == NCI_RF_USER_DISCOVER_REVERT) {
        s_user_listen_tech = -1;
    } else if (listen_tech >= 0) {
        s_user_listen_tech = listen_tech;
    }
    ret = NCI_STATUS_OK;

    if (need_restart) {
        ret = nfa_rf_start_discovery();
        if (ret != NCI_STATUS_OK) {
            NFCLOG_E("start discovery failed, ret = %d", ret);
        }
    }

unlock:
    RELEASE_DISCOVER_LOCK();
    return ret;
}
/**
 * @brief 获取用户自定义的LISTEN技术
 *
 * @return 用户自定义的LISTEN技术
 */
int nfa_rf_get_user_listen_tech() {
    return s_user_listen_tech;
}

/**
 * @brief 设置用户自定义的POLLING技术
 *
 * @return 用户自定义的POLL技术
 */
int nfa_rf_get_user_poll_tech() {
    return s_user_poll_tech;
}

/**
 * @brief 开启RF Discovery
 *
 * @param poll_tech_mask 需要开启的polling技术掩码
 * @param reader_mode 是否开启ReaderMode
 * @param restart 是否重启discovery，当RF Discovery已经开启时如果设置restart为false会直接返回NCI_STATUS_OK，反之会进入IDLE并重新启动discovery
 *
 * @return 成功开启Discovery返回NCI_STATUS_OK，失败返回其他错误码
 */
tNCI_STATUS nfa_rf_enable_discovery(int poll_tech_mask, bool reader_mode, bool restart) {
    NFCLOG_I("poll_tech_mask = %d, reader_mode = %d, restart = %d", poll_tech_mask, reader_mode, restart);
    GET_DISCOVER_LOCK();
    tNCI_STATUS ret = NCI_STATUS_EXT_FAILED;
    if (s_rfst != NCI_RFST_IDLE && !restart) {
        NFCLOG_W("already in discovery state");
        ret = NCI_STATUS_OK;
        goto unlock;
    }
    if (s_rfst != NCI_RFST_IDLE) {
        nfa_rf_stop_discovery();
    }

    uint8_t poll_tech = 0;
    if (poll_tech_mask >= 0) {
        poll_tech = (uint8_t) poll_tech_mask;
    } else {
        // 当传入的poll_tech_mask为负数时，使用config中配置的poll_tech_mask值
        poll_tech = s_poll_tech_mask;
    }
    bool reader_mode_changed = false;
    if (!reader_mode && s_curr_reader_mode) {
        // ReaderMode关闭
        reader_mode_changed = true;
    } else if (poll_tech != 0 && reader_mode && !s_curr_reader_mode) {
        // ReaderMode打开并且Polling也开启
        reader_mode_changed = true;
    }

    if (reader_mode_changed) {
        uint8_t nfcc_config_control = reader_mode ? 0x00 : 0x01;
        uint16_t disc_duration = reader_mode ? DISCOVERY_DURATION_READER_MODE : DISCOVERY_DURATION_DEFAULT;
        uint8_t discovery_duration[] = { disc_duration & 0xFF, (disc_duration >> 8) & 0xFF };
        tNCI_REG regs[] = {
            {.id = NCI_REG_NFCC_CONFIG_CONTROL, .len = 1, .value = &nfcc_config_control},
            {.id = NCI_REG_TOTAL_DURATION, .len = 2, .value = discovery_duration},
        };
        ret = nci_core_set_config(regs, sizeof(regs) / sizeof(tNCI_REG));
        if (ret != NCI_STATUS_OK) {
            NFCLOG_E("set config failed, ret = %d", ret);
        } else {
            s_disc_duration = disc_duration;
        }
    }

    s_poll_tech = poll_tech;
    s_curr_reader_mode = reader_mode;

    ret = nfa_rf_start_discovery();

unlock:
    RELEASE_DISCOVER_LOCK();
    return ret;
}

/**
 * @brief 开关POLLING功能
 *
 * @param is_start 是否开启POLLING，true为开启，false为关闭
 *
 * @return 成功返回NCI_STATUS_OK，失败返回其他错误码
 */
tNCI_STATUS nfa_rf_start_stop_polling(bool is_start) {
    GET_DISCOVER_LOCK();
    tNCI_STATUS ret = NCI_STATUS_EXT_FAILED;

    uint8_t discovery_param = 0;
    if (is_start) {
        discovery_param = NCI_LISTEN_DH_NFCEE_ENABLE_MASK | NCI_POLLING_DH_ENABLE_MASK;
    } else {
        discovery_param = NCI_LISTEN_DH_NFCEE_ENABLE_MASK | NCI_POLLING_DH_DISABLE_MASK;
    }
    tNCI_REG reg = {
        .id = NCI_REG_CON_DISCOVERY_PARAM, .len = 1, .value = &discovery_param,
    };
    ret = nci_core_set_config(&reg, 1);
    if (ret != NCI_STATUS_OK) {
        NFCLOG_E("set config failed, ret = %d", ret);
        goto unlock;
    }

    nfa_rf_stop_discovery();

    if (is_start) {
        // 开启polling，把s_poll_tech设置为config中配置的poll_tech_mask
        s_poll_tech = s_poll_tech_mask;
    } else {
        // 关闭polling，把s_poll_tech设置为0
        s_poll_tech = 0;
    }

    ret = nfa_rf_start_discovery();

unlock:
    RELEASE_DISCOVER_LOCK();
    return ret;
}

/**
 * @brief 设置Discovery Duration为默认
 * @note 只有在Discovery Duration不为默认值时才会设置
 */
static tNCI_STATUS set_default_disc_duration() {
    if (g_dta_mode_enabled) {
        NFCLOG_I("DTA mode enabled, skip set default disc duration");
        return NCI_STATUS_OK;
    }
    if (s_disc_duration == DISCOVERY_DURATION_DEFAULT) {
        return NCI_STATUS_OK;
    }
    uint8_t discovery_duration[] = { DISCOVERY_DURATION_DEFAULT & 0xFF, (DISCOVERY_DURATION_DEFAULT >> 8) & 0xFF };
    tNCI_REG reg = {
        .id = NCI_REG_TOTAL_DURATION, .len = 2, .value = discovery_duration,
    };
    tNCI_STATUS ret = nci_core_set_config(&reg, 1);
    if (ret != NCI_STATUS_OK) {
        NFCLOG_E("set config failed, ret = %d", ret);
        return ret;
    }
    s_disc_duration = DISCOVERY_DURATION_DEFAULT;
    return NCI_STATUS_OK;
}
/**
 * @brief 根据listen_tech设置listen mode config
 * @note 只有在寄存器值真正发生变化时才会真正下发指令设置
 */
static tNCI_STATUS set_listen_mode_config(uint8_t listen_tech) {
    uint8_t la_bit_frame_sdd = 0x04;
    uint8_t la_platform_config = 0x00;
    uint8_t lb_sensb_info = listen_tech & NCI_RF_DISCOVER_LISTEN_B ? 0x01 : 0x00;
    uint8_t lf_protocol_type = listen_tech & NCI_RF_DISCOVER_LISTEN_F ? 0x02 : 0x00;

    tLISTEN_MODE_CONFIG *p_cfg = &s_listen_mode_config;

    tNCI_REG regs[4] = {0};
    uint8_t index = 0;
    if (!p_cfg->is_init || p_cfg->la_bit_frame_sdd != la_bit_frame_sdd) {
        regs[index].id = NCI_REG_LA_BIT_FRAME_SDD;
        regs[index].len = 1;
        regs[index].value = &la_bit_frame_sdd;
        index++;
    }
    if (!p_cfg->is_init || p_cfg->la_platform_config != la_platform_config) {
        regs[index].id = NCI_REG_LA_PLATFORM_CONFIG;
        regs[index].len = 1;
        regs[index].value = &la_platform_config;
        index++;
    }
    if (!p_cfg->is_init || p_cfg->lb_sensb_info != lb_sensb_info) {
        regs[index].id = NCI_REG_LB_SENSB_INFO;
        regs[index].len = 1;
        regs[index].value = &lb_sensb_info;
        index++;
    }
    if (!p_cfg->is_init || p_cfg->lf_protocol_type != lf_protocol_type) {
        regs[index].id = NCI_REG_LF_PROTOCOL_TYPE;
        regs[index].len = 1;
        regs[index].value = &lf_protocol_type;
        index++;
    }
    if (index == 0) {
        return NCI_STATUS_OK;
    }
    tNCI_STATUS ret = nci_core_set_config(regs, index);
    if (ret != NCI_STATUS_OK) {
        NFCLOG_E("set listen mode config failed, ret = %d", ret);
        return ret;
    }
    p_cfg->is_init = true;
    p_cfg->la_bit_frame_sdd = la_bit_frame_sdd;
    p_cfg->la_platform_config = la_platform_config;
    p_cfg->lb_sensb_info = lb_sensb_info;
    p_cfg->lf_protocol_type = lf_protocol_type;
    return NCI_STATUS_OK;
}

/**
 * @brief 启动RF Discovery，并设置RF状态为NCI_RFST_DISCOVERY
 *
 * @note 只能在NCI_RFST_IDLE状态下调用
 * @note 调用成功后，RF状态会变为NCI_RFST_DISCOVERY
 *
 * @return 成功返回NCI_STATUS_OK，失败返回其他错误码
 */
tNCI_STATUS nfa_rf_start_discovery() {
    NFCLOG_D("start discovery");
    GET_DISCOVER_LOCK();
    tNCI_STATUS ret = NCI_STATUS_EXT_FAILED;
    if (s_rfst != NCI_RFST_IDLE) {
        NFCLOG_E("RFST is not idle");
        ret = NCI_STATUS_EXT_STATE_INCORRECT;
        goto unlock;
    }
    // 如果用户设置了poll tech，则使用用户设置的poll tech，反之使用内部设置的poll tech
    uint8_t poll_tech = s_user_poll_tech >= 0 ? (uint8_t) s_user_poll_tech : (s_poll_tech & s_poll_tech_mask);
    // 如果用户设置了listen tech，则使用用户设置的listen tech，反之使用内部设置的listen tech
    uint8_t listen_tech = s_user_listen_tech >= 0 ? (uint8_t) s_user_listen_tech : (s_listen_tech & s_listen_tech_mask);
    if (s_curr_reader_mode) {
        // ReaderMode打开, 关闭Listen
        listen_tech = 0;
        poll_tech = s_poll_tech; // ReaderMode时不用与上mask
    }
    NFCLOG_I("poll_tech = 0x%02X, listen_tech = 0x%02X", poll_tech, listen_tech);
    ret = set_listen_mode_config(listen_tech);
    if (ret != NCI_STATUS_OK) {
        NFCLOG_E("set listen mode config failed, ret = %d", ret);
        goto unlock;
    }
    ret = set_default_disc_duration();
    if (ret != NCI_STATUS_OK) {
        NFCLOG_E("set default disc duration failed, ret = %d", ret);
        goto unlock;
    }
    tNCI_RF_DISCOVER_ENTRY entries[RF_DISCOVER_ENTRY_MAX_SIZE] = {0};
    uint8_t num_entries = 0;
    if (poll_tech & NCI_RF_DISCOVER_POLL_A) {
        entries[num_entries].tech_and_mode = NCI_RF_TECH_A_PASSIVE_POLL_MODE;
        entries[num_entries].discovery_frequency = NCI_RF_DISC_FREQ_EVERY_PERIOD;
        num_entries++;
    }
    if (poll_tech & NCI_RF_DISCOVER_POLL_B) {
        entries[num_entries].tech_and_mode = NCI_RF_TECH_B_PASSIVE_POLL_MODE;
        entries[num_entries].discovery_frequency = NCI_RF_DISC_FREQ_EVERY_PERIOD;
        num_entries++;
    }
    if (poll_tech & NCI_RF_DISCOVER_POLL_F) {
        entries[num_entries].tech_and_mode = NCI_RF_TECH_F_PASSIVE_POLL_MODE;
        entries[num_entries].discovery_frequency = NCI_RF_DISC_FREQ_EVERY_PERIOD;
        num_entries++;
    }
    if (poll_tech & NCI_RF_DISCOVER_POLL_ACTIVE) {
        entries[num_entries].tech_and_mode = NCI_RF_TECH_ACTIVE_POLL_MODE;
        entries[num_entries].discovery_frequency = NCI_RF_DISC_FREQ_EVERY_PERIOD;
        num_entries++;
    }
    if (poll_tech & NCI_RF_DISCOVER_POLL_V) {
        entries[num_entries].tech_and_mode = NCI_RF_TECH_V_PASSIVE_POLL_MODE;
        entries[num_entries].discovery_frequency = NCI_RF_DISC_FREQ_EVERY_PERIOD;
        num_entries++;
    }
    if (listen_tech & NCI_RF_DISCOVER_LISTEN_A) {
        entries[num_entries].tech_and_mode = NCI_RF_TECH_A_PASSIVE_LISTEN_MODE;
        entries[num_entries].discovery_frequency = NCI_RF_DISC_FREQ_EVERY_PERIOD;
        num_entries++;
    }
    if (listen_tech & NCI_RF_DISCOVER_LISTEN_B) {
        entries[num_entries].tech_and_mode = NCI_RF_TECH_B_PASSIVE_LISTEN_MODE;
        entries[num_entries].discovery_frequency = NCI_RF_DISC_FREQ_EVERY_PERIOD;
        num_entries++;
    }
    if (listen_tech & NCI_RF_DISCOVER_LISTEN_F) {
        entries[num_entries].tech_and_mode = NCI_RF_TECH_F_PASSIVE_LISTEN_MODE;
        entries[num_entries].discovery_frequency = NCI_RF_DISC_FREQ_EVERY_PERIOD;
        num_entries++;
    }
    if (listen_tech & NCI_RF_DISCOVER_LISTEN_ACTIVE) {
        entries[num_entries].tech_and_mode = NCI_RF_TECH_ACTIVE_LISTEN_MODE;
        entries[num_entries].discovery_frequency = NCI_RF_DISC_FREQ_EVERY_PERIOD;
        num_entries++;
    }

    ret = nci_rf_discover(entries, num_entries);
    if (ret == NCI_STATUS_OK) {
        update_rfst(NCI_RFST_DISCOVERY);
    }
unlock:
    RELEASE_DISCOVER_LOCK();

    return ret;
}

/**
 * @brief 停止RF Discovery，并回到NCI_RFST_IDLE状态
 *
 * @note 调用成功后，RF状态会变为NCI_RFST_IDLE
 *
 * @return 成功返回NCI_STATUS_OK，失败返回其他错误码
 */
tNCI_STATUS nfa_rf_stop_discovery() {
    NFCLOG_D("stop discovery");
    tNCI_STATUS ret = NCI_STATUS_EXT_FAILED;

    GET_DISCOVER_LOCK();
    osi_atomic_write(&s_deactivate_flag, 1);

    bool wait_ntf = false;
    switch (s_rfst) {
        case NCI_RFST_IDLE:
            NFCLOG_E("RFST is already in idle state");
            ret = NCI_STATUS_OK;
            goto unlock;
        case NCI_RFST_POLL_ACTIVE:
        case NCI_RFST_LISTEN_ACTIVE:
            wait_ntf = true;
            break;
        default:
            break;
    }


    ret = nci_rf_deactivate(NCI_RF_DEACTIVATE_TYPE_IDLE, wait_ntf);
    if (ret == NCI_STATUS_OK) {
        update_rfst(NCI_RFST_IDLE);
    }

unlock:
    osi_atomic_write(&s_deactivate_flag, 0);
    RELEASE_DISCOVER_LOCK();
    return ret;
}

#if IS_FEATURE_ON(NCI_FEATURE_RW)

static tNCI_STATUS rf_restart_discovery_wait_activated(uint32_t timeout, tNCI_RF_INTF_ACTIVATED_PARAMS *p_activated_data) {
    s_p_wait_activated_params = p_activated_data;
    s_block_send_tag_lost_evt = true;
    tNCI_STATUS ret = nfa_rf_stop_discovery();
    if (ret != NCI_STATUS_OK) {
        NFCLOG_E("stop discovery failed, ret=%d", ret);
        goto cleanup;
    }
    ret = nfa_rf_start_discovery();
    if (ret != NCI_STATUS_OK) {
        NFCLOG_E("start discovery failed, ret=%d", ret);
        goto cleanup;
    }
    if (osi_mutex_wait(&s_discover_lock, timeout) != NFC_STATUS_OK) {
        NFCLOG_E("wait discover lock failed");
        // 没有等到卡片激活，返回NCI_STATUS_DISCOVERY_TARGET_ACTIVATION_FAILED
        ret = NCI_STATUS_DISCOVERY_TARGET_ACTIVATION_FAILED;
        goto cleanup;
    }
cleanup:
    s_p_wait_activated_params = NULL;
    s_block_send_tag_lost_evt = false;
    if (ret != NCI_STATUS_OK) {
        // 卡片没有激活成功时通知卡片丢失
        nci_task_post(NCI_TASK_EVT_RW_TAG_LOSTED, 0, 0, NULL);
    }
    return ret;
}

/**
 * @brief 发送RF_SELECT命令，并可以等待卡片激活
 *
 * @note 此函数不会去获取Discover锁，需要调用方确保Discover锁已获取
 * @note 如果此函数调用中发现失败，会尝试将RF状态恢复到Discovery状态
 *
 * @param id 待激活的卡片ID
 * @param protocol 使用哪种协议激活
 * @param interface 使用哪个接口激活
 * @param timeout 等待激活超时时间
 * @param p_activated_data 激活后返回的参数，如果为NULL则不等待激活
 *
 * @return 成功返回NCI_STATUS_OK，失败返回其他错误码
 */
static tNCI_STATUS rf_select_no_lock(tNCI_RF_DISCOVERY_ID id, tNCI_RF_PROTOCOL protocol, tNCI_RF_INTERFACE interface, uint32_t timeout, tNCI_RF_INTF_ACTIVATED_PARAMS *p_activated_data) {
    if (s_rfst != NCI_RFST_W4_HOST_SELECT) {
        NFCLOG_E("RFST is not W4_HOST_SELECT");
        return NCI_STATUS_EXT_STATE_INCORRECT;
    }
    tNCI_STATUS ret = NCI_STATUS_EXT_FAILED;
    if (p_activated_data) {
        ret = nci_rf_select_wait_activated(id, protocol, interface, timeout, p_activated_data);
        if (ret == NCI_STATUS_DISCOVERY_TARGET_ACTIVATION_FAILED) {
            // 激活失败，尝试重新启动Discovery并再次等待激活
            ret = rf_restart_discovery_wait_activated(timeout, p_activated_data);
        }
    } else {
        // 不需要等待卡片激活，直接发送select指令
        ret = nci_rf_discovery_select(id, protocol, interface);
    }
    if (ret == NCI_STATUS_OK) {
        if (p_activated_data) {
            update_rfst(NCI_RFST_POLL_ACTIVE);
            // 检查激活的卡片信息是否和选择的是否一致，允许Interface不一致
            if (p_activated_data->id != id || p_activated_data->protocol != protocol) {
                // 激活的卡片信息和选择的不一致
                NFCLOG_E("activated data is not match, select (id=0x%02X, protocol=0x%02X, interface=0x%02X), activated (id=0x%02X, protocol=0x%02X, interface=0x%02X", id, protocol, interface, p_activated_data->id, p_activated_data->protocol, p_activated_data->interface);
                ret = NCI_STATUS_EXT_FAILED;
                if (rf_deactivate(false) != NCI_STATUS_OK) {
                    NFCLOG_E("rf_deactivate failed");
                }
            } else if (p_activated_data->interface != interface) {
                // 激活的卡片Interface和选择的不一致
                NFCLOG_W("activated interface is not match, select (id=0x%02X, protocol=0x%02X, interface=0x%02X), activated (id=0x%02X, protocol=0x%02X, interface=0x%02X", id, protocol, interface, p_activated_data->id, p_activated_data->protocol, p_activated_data->interface);
            }
        } else {
            // 没有等待NTF，切换到W4_HOST_SELECT状态
            update_rfst(NCI_RFST_W4_HOST_SELECT);
        }
    } else {
        // 将RF状态恢复到Discovery状态
        switch (s_rfst) {
            case NCI_RFST_POLL_ACTIVE:
            case NCI_RFST_W4_HOST_SELECT:
                nfa_rf_stop_discovery();
                __attribute__((fallthrough));
            case NCI_RFST_IDLE:
                nfa_rf_start_discovery();
                break;
            default:
                break;
        }
    }
    return ret;
}

/**
 * @brief 选择卡片进行激活
 *
 * @param id 被激活的卡片ID
 * @param protocol 使用哪种协议激活
 * @param interface 使用哪个接口激活
 * @param timeout 等待激活超时时间
 * @param p_activated_data 激活后返回的参数，如果为NULL则不等待激活
 *
 * @return 成功返回NCI_STATUS_OK，失败返回其他错误码
 */
tNCI_STATUS rf_select(tNCI_RF_DISCOVERY_ID id, tNCI_RF_PROTOCOL protocol, tNCI_RF_INTERFACE interface, uint32_t timeout, tNCI_RF_INTF_ACTIVATED_PARAMS *p_activated_data) {
    NFCLOG_D("id=0x%02X, protocol=0x%02X, interface=0x%02X", id, protocol, interface);
    GET_DISCOVER_LOCK();
    tNCI_STATUS ret = rf_select_no_lock(id, protocol, interface, timeout, p_activated_data);
    RELEASE_DISCOVER_LOCK();
    return ret;
}

/**
 * @brief 重新选择卡片进行激活
 *
 * @note 要求当前状态为POLL_ACTIVE
 * @note 会先sleep，再重新选择激活
 *
 * @param id 被激活的卡片ID
 * @param protocol 使用哪种协议激活
 * @param interface 使用哪个接口激活
 * @param timeout 等待激活超时时间
 *
 * @return 成功返回NCI_STATUS_OK，失败返回其他错误码
 */
tNCI_STATUS rf_re_select(tNCI_RF_DISCOVERY_ID id, tNCI_RF_PROTOCOL protocol, tNCI_RF_INTERFACE interface, uint32_t timeout) {
    GET_DISCOVER_LOCK();
    tNCI_STATUS ret = NCI_STATUS_EXT_FAILED;
    tNCI_RF_INTF_ACTIVATED_PARAMS *p_params = NULL;
    if (s_rfst != NCI_RFST_POLL_ACTIVE) {
        NFCLOG_E("RFST is not POLL_ACTIVE");
        ret = NCI_STATUS_EXT_STATE_INCORRECT;
        goto unlock;
    }
    ret = rf_deactivate(true);
    if (ret != NCI_STATUS_OK) {
        goto unlock;
    }

    p_params = osi_calloc(sizeof(tNCI_RF_INTF_ACTIVATED_PARAMS));
    if (p_params == NULL) {
        NFCLOG_E("malloc failed");
        ret = NCI_STATUS_EXT_ALLOC_FAILED;
        goto unlock;
    }

    ret = rf_select_no_lock(id, protocol, interface, timeout, p_params);

unlock:
    if (p_params) {
        osi_free(p_params);
    }
    RELEASE_DISCOVER_LOCK();
    return ret;
}
#endif // IS_FEATURE_ON(NCI_FEATURE_RW)

#if IS_FEATURE_ON(NCI_FEATURE_RW_T3T)
/**
 * @brief 发送T3T识别码
 * @param[in] sensf_req T3T识别码请求参数
 * @param[out] sensf_res_list T3T识别码响应列表
 * @param[inout] res_count 返回的T3T识别码响应列表个数, 传入时为最大返回个数，返回时为实际返回个数
 * @return 成功返回NCI_STATUS_OK，失败返回其他错误码
 */
tNCI_STATUS rf_t3t_polling(tNCI_RF_SENSF_REQ_PARAMS sensf_req, tNCI_RF_SENSF_RES *sensf_res_list, uint8_t *res_count) {
    GET_DISCOVER_LOCK();
    tNCI_STATUS ret = NCI_STATUS_EXT_FAILED;
    if (s_rfst != NCI_RFST_POLL_ACTIVE) {
        NFCLOG_E("RFST is not POLL_ACTIVE, can not transmit t3t data");
        ret = NCI_STATUS_EXT_STATE_INCORRECT;
        goto unlock;
    }
    ret = nci_rf_t3t_polling(sensf_req, sensf_res_list, res_count);
unlock:
    RELEASE_DISCOVER_LOCK();
    return ret;
}
#endif // IS_FEATURE_ON(NCI_FEATURE_RW_T3T)

#if IS_FEATURE_ON(NCI_FEATURE_RW_T4T)
/**
 * @brief 发送T4T NAK_PRESENCE指令
 * @note 只有在当前RF状态为NCI_RFST_POLL_ACTIVE时才能发送此指令
 * @return 成功返回NCI_STATUS_OK，失败返回其他错误码
 */
tNCI_STATUS rf_t4t_nak_presence() {
    GET_DISCOVER_LOCK();
    tNCI_STATUS ret = NCI_STATUS_EXT_FAILED;
    if (s_rfst != NCI_RFST_POLL_ACTIVE) {
        NFCLOG_E("RFST is not POLL_ACTIVE, can not do t4t nak presence");
        ret = NCI_STATUS_EXT_STATE_INCORRECT;
        goto unlock;
    }
    ret = nci_rf_iso_dep_nak_presence();
unlock:
    RELEASE_DISCOVER_LOCK();
    return ret;
}
#endif // IS_FEATURE_ON(NCI_FEATURE_RW_T4T)

#if IS_FEATURE_ON(NCI_FEATURE_RW) || IS_FEATURE_ON(NCI_FEATURE_CE)
/**
 * @brief 去激活
 *
 * @note 当当前状态为NCI_RFST_POLL_ACTIVE或NCI_RFST_LISTEN_ACTIVE时，调用此函数可以切换到SLEEP或Discovery状态
 * @note 当当前状态为NCI_RFST_W4_ALL_DISCOVERIES时，调用此函数可以切换到IDLE状态
 *
 * @param is_sleep 是否切换到SLEEP状态，true为切换到SLEEP状态，false为切换到Discovery状态
 *
 * @return 成功返回NCI_STATUS_OK，失败返回其他错误码
 */
tNCI_STATUS rf_deactivate(bool is_sleep) {
    NFCLOG_D("deactivate is_sleep = %d", is_sleep);
    tNCI_STATUS ret = NCI_STATUS_EXT_FAILED;
    tNCI_RF_DEACTIVATE_TYPE deactivate_type = NCI_RF_DEACTIVATE_TYPE_IDLE;
    tNCI_RFST new_rfst = NCI_RFST_IDLE;
    bool wait_ntf = false;
    GET_DISCOVER_LOCK();
    osi_atomic_write(&s_deactivate_flag, 1);
    switch (s_rfst) {
        case NCI_RFST_POLL_ACTIVE:
            deactivate_type = (is_sleep) ? NCI_RF_DEACTIVATE_TYPE_SLEEP : NCI_RF_DEACTIVATE_TYPE_DISCOVERY;
            wait_ntf = true;
            new_rfst = (is_sleep) ? NCI_RFST_W4_HOST_SELECT : NCI_RFST_DISCOVERY;
            break;
        case NCI_RFST_LISTEN_ACTIVE:
            deactivate_type = (is_sleep) ? NCI_RF_DEACTIVATE_TYPE_SLEEP : NCI_RF_DEACTIVATE_TYPE_DISCOVERY;
            wait_ntf = true;
            new_rfst = (is_sleep) ? NCI_RFST_LISTEN_SLEEP : NCI_RFST_DISCOVERY;
            break;
        case NCI_RFST_W4_ALL_DISCOVERIES:
            deactivate_type = NCI_RF_DEACTIVATE_TYPE_IDLE;
            wait_ntf = false;
            new_rfst = NCI_RFST_IDLE;
            break;
        default:
            NFCLOG_E("RFST is not active, can not deactivate");
            ret = NCI_STATUS_EXT_STATE_INCORRECT;
            goto unlock;
    }

    ret = nci_rf_deactivate(deactivate_type, wait_ntf);
    if (ret == NCI_STATUS_OK) {
        update_rfst(new_rfst);
    }
unlock:
    osi_atomic_write(&s_deactivate_flag, 0);
    RELEASE_DISCOVER_LOCK();
    return ret;
}

/**
 * @brief 向RF通道发送Data数据
 *
 * @note 只有在POLL_ACTIVE或LISTEN_ACTIVE状态才能发送Data数据
 *
 * @param[in] cmd 待发送的Data数据
 * @param[out] rsp 接收到的Data数据
 * @param[in] timeout 等待rsp的超时时间
 *
 * @return 成功返回NCI_STATUS_OK，失败返回其他错误码
 */
tNCI_STATUS rf_transmit(tNCI_BUF *cmd, tNCI_BUF *rsp, uint32_t timeout) {
    if (cmd == NULL || rsp == NULL) {
        NFCLOG_E("param is invalide");
        return NCI_STATUS_EXT_INVALID_PARAM;
    }
    GET_DISCOVER_LOCK();
    tNCI_STATUS ret = NCI_STATUS_EXT_FAILED;
    if (s_rfst != NCI_RFST_POLL_ACTIVE && s_rfst != NCI_RFST_LISTEN_ACTIVE) {
        NFCLOG_E("RFST is not POLL_ACTIVE or LISTEN_ACTIVE, can not transmit rf data");
        ret = NCI_STATUS_EXT_STATE_INCORRECT;
        goto unlock;
    }
    ret = nci_data_channel_transmit(NCI_DATA_CHANNEL_RF, cmd, rsp, timeout);
    if (ret != NCI_STATUS_OK) {
        NFCLOG_E("nci_data_channel_transmit failed, ret=%d", ret);
    }
unlock:
    RELEASE_DISCOVER_LOCK();
    return ret;
}

/**
 * @brief 向RF通道发送Data数据,异步方式，不等待RSP
 *
 * @note 只有在POLL_ACTIVE或LISTEN_ACTIVE状态才能发送Data数据
 *
 * @param[in] cmd 待发送的Data数据
 *
 * @return 成功返回NCI_STATUS_OK，失败返回其他错误码
 */
tNCI_STATUS rf_transmit_async(tNCI_BUF *cmd) {
    if (cmd == NULL) {
        NFCLOG_E("param is invalide");
        return NCI_STATUS_EXT_INVALID_PARAM;
    }
    GET_DISCOVER_LOCK();
    tNCI_STATUS ret = NCI_STATUS_EXT_FAILED;
    if (s_rfst != NCI_RFST_POLL_ACTIVE && s_rfst != NCI_RFST_LISTEN_ACTIVE) {
        NFCLOG_E("RFST is not POLL_ACTIVE or LISTEN_ACTIVE, can not transmit rf data");
        ret = NCI_STATUS_EXT_STATE_INCORRECT;
        goto unlock;
    }
    ret = nci_data_channel_transmit_async(NCI_DATA_CHANNEL_RF, cmd);
    if (ret != NCI_STATUS_OK) {
        NFCLOG_E("nci_data_channel_transmit_async failed, ret=%d", ret);
    }
unlock:
    RELEASE_DISCOVER_LOCK();
    return ret;
}
#endif // IS_FEATURE_ON(NCI_FEATURE_RW) || IS_FEATURE_ON(NCI_FEATURE_CE)

/**
 * @brief 多协议卡片被发现时回调
 *
 * @param p_params 发现参数
 *
 * @return 成功返回NCI_STATUS_OK，失败返回其他错误码
 */
tNCI_STATUS on_rf_discovered(tNCI_RF_DISCOVER_PARAMS *p_params) {
    GET_DISCOVER_LOCK();
    tNCI_STATUS ret = NCI_STATUS_EXT_FAILED;
    if (s_rfst != NCI_RFST_DISCOVERY && s_rfst != NCI_RFST_W4_ALL_DISCOVERIES) {
        NFCLOG_E("RFST is not in DISCOVERY or W4_ALL_DISCOVERIES state");
        ret = NCI_STATUS_EXT_STATE_INCORRECT;
        goto unlock;
    }
    if (s_rfst == NCI_RFST_DISCOVERY) {
        // 当前是Discovery状态, 分配内存并将发现参数拷贝到内存中
        if (s_p_discover_params) {
            NFCLOG_D("free old s_p_discover_params");
            osi_free(s_p_discover_params);
        }
        s_p_discover_params = osi_malloc(sizeof(tNCI_RF_DISCOVER_PARAMS) * RF_DISCOVER_PARAM_MAX_SIZE);
        if (!s_p_discover_params) {
            NFCLOG_E("malloc failed");
            ret = NCI_STATUS_EXT_ALLOC_FAILED;
            goto unlock;
        }
        s_discover_params_size = 0;
        if (!osi_memcpy_s(&s_p_discover_params[s_discover_params_size], sizeof(tNCI_RF_DISCOVER_PARAMS), p_params, sizeof(tNCI_RF_DISCOVER_PARAMS))) {
            NFCLOG_E("memcpy failed");
            osi_free(s_p_discover_params);
            s_p_discover_params = NULL;
            ret = NCI_STATUS_EXT_COPY_FAILED;
            goto unlock;
        }
        s_discover_params_size++;
        update_rfst(NCI_RFST_W4_ALL_DISCOVERIES);
    } else if (s_rfst == NCI_RFST_W4_ALL_DISCOVERIES) {
        // 当前是W4_ALL_DISCOVERIES状态, 将发现参数拷贝到内存中
        if (!s_p_discover_params) {
            NFCLOG_E("s_p_discover_params is NULL");
            ret = NCI_STATUS_EXT_FAILED;
            goto unlock;
        }
        if (s_discover_params_size >= RF_DISCOVER_PARAM_MAX_SIZE) {
            NFCLOG_E("s_p_discover_params is full");
            ret = NCI_STATUS_EXT_FAILED;
            goto unlock;
        }
        if (!osi_memcpy_s(&s_p_discover_params[s_discover_params_size], sizeof(tNCI_RF_DISCOVER_PARAMS), p_params, sizeof(tNCI_RF_DISCOVER_PARAMS))) {
            NFCLOG_E("memcpy failed");
            ret = NCI_STATUS_EXT_COPY_FAILED;
            goto unlock;
        }
        s_discover_params_size++;
        if (p_params->is_last) {
            // 是最后一条发现通知了，通知读卡模块进行处理
            update_rfst(NCI_RFST_W4_HOST_SELECT);
            if (NCI_STATUS_OK != nci_task_post(NCI_TASK_EVT_RW_TAG_DISCOVERED, s_discover_params_size, 0, s_p_discover_params)) {
                NFCLOG_E("notify tag discovered failed");
            } else {
                // 通知读卡模块成功，s_rf_discover_params交由读卡模块处理
                s_p_discover_params = NULL;
                s_discover_params_size = 0;
            }
        } else {
            NFCLOG_I("wait for next discovery");
        }
    }
    ret = NCI_STATUS_OK;
unlock:
    RELEASE_DISCOVER_LOCK();
    return ret;
}

/**
 * @brief 处理RF接口激活的事件
 *
 * @param p_params 激活参数
 *
 * @return 成功返回NCI_STATUS_OK，失败返回其他错误码
 */
tNCI_STATUS on_rf_intf_activated(tNCI_RF_INTF_ACTIVATED_PARAMS *p_params) {
    tNCI_STATUS ret = NCI_STATUS_EXT_FAILED;
    GET_DISCOVER_LOCK();
    NFCLOG_I("get lock");
    switch (s_rfst)
    {
    case NCI_RFST_DISCOVERY:
    case NCI_RFST_W4_HOST_SELECT:
    case NCI_RFST_LISTEN_SLEEP:
        break;
    default:
        NFCLOG_E("RFST is not in DISCOVERY、W4_HOST_SELECT or LISTEN_SLEEP state");
        ret = NCI_STATUS_EXT_STATE_INCORRECT;
        goto unlock;
    }
    if (p_params->interface == NCI_RF_INTERFACE_ITAP || p_params->protocol == NCI_RF_PROTOCOL_ITAP) {
        p_params->interface = NCI_RF_INTERFACE_ISO_DEP;
        p_params->protocol = NCI_RF_PROTOCOL_ISO_DEP;
        NFCLOG_I("iTAP activated");
    }
    uint8_t mdpps = p_params->max_data_packet_payload_size;
    if (p_params->interface == NCI_RF_INTERFACE_ISO_DEP) {
        // ISO_DEP协议的payload大小为253
        mdpps = NCI_RF_ISO_DEP_MAX_DATA_PAYLOAD_SIZE;
    }
    ret = nci_data_set_channel_info(NCI_DATA_CHANNEL_RF, mdpps, p_params->initial_number_of_credits);
    if (ret != NCI_STATUS_OK) {
        NFCLOG_E("nci_data_set_channel_info failed, ret=%d", ret);
    }
    ret = NCI_STATUS_OK;
    if (s_p_wait_activated_params) {
        // 有等待激活的参数，将激活参数拷贝到等待激活的参数中
        if (!osi_memcpy_s(s_p_wait_activated_params, sizeof(tNCI_RF_INTF_ACTIVATED_PARAMS), p_params, sizeof(tNCI_RF_INTF_ACTIVATED_PARAMS))) {
            NFCLOG_E("memcpy failed");
            ret = NCI_STATUS_EXT_COPY_FAILED;
        }
        // 通知等待激活的线程
        osi_mutex_notify(&s_discover_lock);
        goto unlock;
    }
    bool is_poll_mode = p_params->activation_tech_mode < NCI_RF_TECH_A_PASSIVE_LISTEN_MODE && p_params->interface != NCI_RF_INTERFACE_NFCEE_DIRECT;
    if (is_poll_mode) {
        if (s_rfst == NCI_RFST_DISCOVERY) {
            // 只在DISCOVERY状态才通知读卡模块
            if (NCI_STATUS_OK == nci_task_post(NCI_TASK_EVT_RW_TAG_ACTIVATED, 0, 0, p_params)) {
                // 通知读卡模块成功，p_params交由读卡模块处理
                ret = NCI_STATUS_EXT_NOT_FREE;
            }
        } else {
            NFCLOG_E("received activated event when RFST is not in DISCOVERY state, not notify rw module");
        }
    } else {
        if (s_rfst == NCI_RFST_DISCOVERY || s_rfst == NCI_RFST_LISTEN_SLEEP) {
            // 只在DISCOVERY和LISTEN_SLEEP状态才通知卡模拟模块
            if (NCI_STATUS_OK == nci_task_post(NCI_TASK_EVT_CE_ACTIVATED, 0, 0, p_params)) {
                // 通知卡模拟模块成功，p_params交由卡模拟模块处理
                ret = NCI_STATUS_EXT_NOT_FREE;
            }
        } else {
            NFCLOG_E("received activated event when RFST is not in DISCOVERY or LISTEN_SLEEP state, not notify ce module");
        }
    }

    update_rfst(is_poll_mode ? NCI_RFST_POLL_ACTIVE : NCI_RFST_LISTEN_ACTIVE);
unlock:
    RELEASE_DISCOVER_LOCK();
    return ret;
}

/**
 * @brief 处理RF接口去激活事件
 *
 * @param type 去激活的类型
 * @param reason 去激活的原因
 *
 * @return 成功返回NCI_STATUS_OK，失败返回其他错误码
 */
tNCI_STATUS on_rf_deactivated(tNCI_RF_DEACTIVATE_TYPE type, tNCI_RF_DEACTIVATE_REASON reason) {
    GET_DISCOVER_LOCK();
    tNCI_STATUS ret = NCI_STATUS_EXT_FAILED;
    tNCI_RFST new_state = NCI_RFST_IDLE;
    switch (s_rfst)
    {
    case NCI_RFST_LISTEN_ACTIVE:
        if (type == NCI_RF_DEACTIVATE_TYPE_IDLE) {
            // LISTEN_ACTIVE状态切换到IDLE状态必须通过DH主动发起，无需在这里处理
            ret = NCI_STATUS_EXT_STATE_INCORRECT;
            goto unlock;
        } else if (type == NCI_RF_DEACTIVATE_TYPE_DISCOVERY) {
            new_state = NCI_RFST_DISCOVERY;
        } else if (type == NCI_RF_DEACTIVATE_TYPE_SLEEP || type == NCI_RF_DEACTIVATE_TYPE_SLEEP_AF) {
            new_state = NCI_RFST_LISTEN_SLEEP;
        }
        break;
    case NCI_RFST_LISTEN_SLEEP:
        if (type != NCI_RF_DEACTIVATE_TYPE_DISCOVERY) {
            // LISTEN_SLEEP状态切换到其他状态必须通过DH主动发起，无需在这里处理
            ret = NCI_STATUS_EXT_STATE_INCORRECT;
            goto unlock;
        }
        new_state = NCI_RFST_DISCOVERY;
        break;
    default:
        // 只有LISTEN_ACTIVE和LISTEN_SLEEP状态才能通过FW的deactivate ntf来切换RFST，
        // 其他状态都是DH主动发起的，不需要在这里处理
        ret = NCI_STATUS_EXT_STATE_INCORRECT;
        goto unlock;
    }

    update_rfst(new_state);
    nci_task_post(NCI_TASK_EVT_CE_DEACTIVATED, 0, 0, NULL);
    ret = NCI_STATUS_OK;
unlock:
    if (ret != NCI_STATUS_OK) {
        NFCLOG_E("handle unexpected deactivate event, rfst=%s(%d), type=%d, reason=%d", s_rfst_name[s_rfst], s_rfst, type, reason);
    }
    RELEASE_DISCOVER_LOCK();
    return ret;
}

/**
 * @brief 处理RF接口错误事件
 *
 * @param status 状态码
 */
void on_rf_error(tNCI_STATUS status) {
    NFCLOG_I("status=%d", status);
    if (status == NCI_STATUS_OK) {
        NFCLOG_W("unexpected status=0");
        return;
    }
    if (osi_atomic_read(&s_deactivate_flag)) {
        NFCLOG_I("deactivate flag is set, ignore error event");
        return;
    }
    if (rf_lock() != NCI_STATUS_OK) {
        NFCLOG_E("rf_lock failed");
        return;
    }

    tNCI_STATUS ret = NCI_STATUS_EXT_FAILED;

    if (s_rfst == NCI_RFST_POLL_ACTIVE) {
        // 卡片在激活状态下，发送deactivate任务，切换到Discovery状态
        ret = rf_deactivate(false);
        if (ret != NCI_STATUS_OK) {
            NFCLOG_E("rf_deactivate failed, status=%d", ret);
        }
    } else if (s_rfst == NCI_RFST_IDLE) {
        // 在IDLE状态下不做任何处理
        NFCLOG_I("ignore error event, rfst=%s(%d), status=%d", s_rfst_name[s_rfst], s_rfst, status);
    } else {
        // 其他状态下，直接重启Discovery
        NFCLOG_I("receive error event, rfst=%s(%d), status=%d, restart rf discovery", s_rfst_name[s_rfst], s_rfst, status);
        ret = nfa_rf_stop_discovery();
        if (ret != NCI_STATUS_OK) {
            NFCLOG_E("nfa_rf_stop_discovery failed, status=%d", ret);
        }
        ret = nfa_rf_start_discovery();
        if (ret != NCI_STATUS_OK) {
            NFCLOG_E("nfa_rf_start_discovery failed, status=%d", ret);
        }
    }
    rf_unlock();
}

/**
 * @brief 处理Discover模块的任务
 */
static bool disc_task_handle(uint32_t what, uint32_t arg1, uint64_t arg2, void* args) {
    (void) arg2;
    (void) args;
    tNCI_STATUS ret = NCI_STATUS_EXT_FAILED;
    switch (what) {
        case NCI_TASK_EVT_DISC_DEACTIVATE:
            ret = rf_deactivate(arg1 != 0);
            if (ret != NCI_STATUS_OK) {
                NFCLOG_E("deactivate failed, status=%d", ret);
            }
            break;
        case NCI_TASK_EVT_DISC_RESTART_DISCOVERY:
            ret = rf_lock();
            if (ret != NCI_STATUS_OK) {
                NFCLOG_E("rf_lock failed, status=%d", ret);
                break;
            }
            ret = nfa_rf_stop_discovery();
            if (ret != NCI_STATUS_OK) {
                NFCLOG_E("nfa_rf_stop_discovery failed, status=%d", ret);
            }
            ret = nfa_rf_start_discovery();
            if (ret != NCI_STATUS_OK) {
                NFCLOG_E("nfa_rf_start_discovery failed, status=%d", ret);
            }
            rf_unlock();
            break;
        default:
            NFCLOG_E("unexpected event, what=%d", what);
            break;
    }
    return true;
}
/**
 * @brief Discover模块任务清理函数
 */
static void disc_task_cleanup(uint32_t what, uint32_t arg1, uint64_t arg2, void* args) {
    (void) what;
    (void) arg1;
    (void) arg2;
    if (args) {
        osi_free(args);
    }
}

/**
 * @brief Discover模块初始化函数
 */
static tNCI_STATUS init(const tNCI_MODULE_INIT_CFG *p_cfg) {
    (void) p_cfg;
    if (osi_mutex_init_with_attr(&s_discover_lock, true) != NFC_STATUS_OK) {
        NFCLOG_E("init mutex failed");
        return NCI_STATUS_EXT_FAILED;
    }
    tNCI_STATUS ret = NCI_STATUS_EXT_FAILED;
    if (nci_task_register(disc_task_handle, disc_task_cleanup, NCI_TASK_EVT_DISC_GROUP) != NCI_STATUS_OK) {
        NFCLOG_E("register task failed");
        ret = NCI_STATUS_EXT_FAILED;
        goto cleanup;
    }

    GET_DISCOVER_LOCK();

    const tNFC_CF *p_cf = nfc_config_get();

    s_poll_tech_mask = p_cf->polling_tech_mask;
    s_listen_tech_mask = p_cf->vendor_cf.host_listen_tech_mask;
    s_poll_tech = s_poll_tech_mask;
    s_listen_tech = s_listen_tech_mask;
    s_rfst = NCI_RFST_IDLE;
    s_user_listen_tech = -1;
    s_user_poll_tech = -1;
    s_p_wait_activated_params = NULL;
    s_block_send_tag_lost_evt = false;
    osi_atomic_write(&s_deactivate_flag, 0);
    osi_memset_s(&s_listen_mode_config, sizeof(tLISTEN_MODE_CONFIG), 0, sizeof(tLISTEN_MODE_CONFIG));
    s_disc_duration = 0;

    NFCLOG_I("poll_tech_mask=0x%02X, listen_tech_mask=0x%02X", s_poll_tech_mask, s_listen_tech_mask);

    ret = nci_rf_discover_map(s_rf_discover_map, s_rf_discover_map_size);
cleanup:
    RELEASE_DISCOVER_LOCK();
    if (ret != NCI_STATUS_OK) {
        osi_mutex_deinit(&s_discover_lock);
    }
    return ret;
}

/**
 * @brief Discover模块退出函数
 */
static tNCI_STATUS deinit(bool is_shutdown) {
    GET_DISCOVER_LOCK();
    s_poll_tech_mask = 0;
    s_listen_tech_mask = 0;
    s_poll_tech = 0;
    s_listen_tech = 0;
    s_user_poll_tech = -1;
    s_user_listen_tech = -1;
    osi_atomic_write(&s_deactivate_flag, 0);

    NFCLOG_I("deinit enter, s_rfst=%d", s_rfst);

    if (!is_shutdown && s_rfst != NCI_RFST_IDLE) {
        nfa_rf_stop_discovery();
    }
    // 无论如何都将软件的RFST状态切换到IDLE
    update_rfst(NCI_RFST_IDLE);
    RELEASE_DISCOVER_LOCK();

    if (nci_task_unregister(NCI_TASK_EVT_DISC_GROUP) != NCI_STATUS_OK) {
        NFCLOG_E("unregister task failed");
    }

    osi_mutex_deinit(&s_discover_lock);
    return NCI_STATUS_OK;
}

void discover_dump(int fd) {
    osi_dump(fd, "rfst = %s(%d)", s_rfst_name[s_rfst], s_rfst);
    osi_dump(fd, "poll_tech = 0x%02X, listen_tech = 0x%02X", s_poll_tech, s_listen_tech);
    osi_dump(fd, "poll_tech_mask = 0x%02X, listen_tech_mask = 0x%02X", s_poll_tech_mask, s_listen_tech_mask);
    osi_dump(fd, "user_listen_tech = %d", s_user_listen_tech);
    osi_dump(fd, "reader_mode = %d", s_curr_reader_mode);
}

/** @brief Discover管理模块定义 */
tNCI_MODULE g_discover_manager = {
    .name = "DISCOVER_MANAGER",
    .state = NCI_MODULE_STATE_DISABLED,
    .init = init,
    .deinit = deinit,
    .dump = discover_dump,
};

/**
 * @brief 获取RF锁
 *
 * @note 获取锁成功后，调用者需要调用rf_unlock()释放锁
 *
 * @return 成功返回NCI_STATUS_OK，失败返回其他错误码
 */
tNCI_STATUS rf_lock() {
    return osi_mutex_lock(&s_discover_lock) == NFC_STATUS_OK ? NCI_STATUS_OK : NCI_STATUS_EXT_GET_LOCK_FAILED;
}

/**
 * @brief 释放RF锁
 *
 * @note 调用者需要先调用rf_lock()获取锁，然后才能调用此函数释放锁
 *
 * @return 成功返回NCI_STATUS_OK，失败返回其他错误码
 */
tNCI_STATUS rf_unlock() {
    return osi_mutex_unlock(&s_discover_lock) == NFC_STATUS_OK ? NCI_STATUS_OK : NCI_STATUS_EXT_FAILED;
}
